import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'linphone_chat_message.dart';

enum MessageState {
  Created,
  InProgress,
  DeliveredToUser,
  Delivered,
  NotDelivered,
  FileTransferDone,
}

abstract class ChatMessageListener {
  void onMsgStateChanged(MessageState state) {
  }
}

class LinphoneChatMessage {
  LinphoneChatMessage._private();
  int localTime = DateTime.now().millisecondsSinceEpoch;
  String? message;
  String? to;
  MessageState messageState = MessageState.Created;
  ChatMessageListener? listener;

  LinphoneChatMessage() {

  }

  static LinphoneChatMessage create(String message) {
    var chatMessage = LinphoneChatMessage();
    chatMessage.message = message;
    return chatMessage;
  }

  void setListener(ChatMessageListener listener) {
    this.listener = listener;
    if(listener!=null) {
      ChatMessageManage.getInstance.addMessage(this);
    }else{
      ChatMessageManage.getInstance.removeMessage(localTime.toString());
    }
  }

  void msgChangeState(MessageState messageState) {
    this.messageState = messageState;
    listener?.onMsgStateChanged(messageState);
  }
}

class ChatMessageManage {
  ChatMessageManage._private();
  static const eventChannel = const EventChannel('linphone_flutter/message');
  static ChatMessageManage? _instance;
  static ChatMessageManage get getInstance =>
      _instance = _instance ?? ChatMessageManage._internal();
  Map<String, LinphoneChatMessage> cacheHandleMap = {};

  ChatMessageManage._internal() {
    eventChannel?.receiveBroadcastStream().listen((dynamic res) {
      if (res["type"] == "messageState") {
        String localTime = res["localTime"].toString();
        LinphoneChatMessage? handle = cacheHandleMap[localTime];
        if (res["result"] == "InProgress") {
          handle?.msgChangeState(MessageState.InProgress);
        } else if (res["result"] == "DeliveredToUser") {
          handle?.msgChangeState(MessageState.DeliveredToUser);
        } else if (res["result"] == "Delivered") {
          handle?.msgChangeState(MessageState.Delivered);
        } else if (res["result"] == "NotDelivered") {
          handle?.msgChangeState(MessageState.NotDelivered);
        } else if (res["result"] == "FileTransferDone") {
          handle?.msgChangeState(MessageState.FileTransferDone);
        }
      }
    });
  }

  void addMessage(LinphoneChatMessage message) {
    cacheHandleMap[message.localTime.toString()] = message;
  }

  void removeMessage(String key) {
    if (cacheHandleMap.containsKey(key)) {
      cacheHandleMap.remove(key);
    }
  }
}